/**
 * 图层管理器
 * @description 统一管理各种类型的地图图层，提供图层的增删改查功能
 */

import { ref } from 'vue';
import {
  WMS_PARAMETERS,
  ASSETS,
  STATIC_SERVER_IP,
  LAYER_URLS
} from '../constants.js';

/**
 * 图层管理器类
 * @class LayerManager
 */
export class LayerManager {
  constructor(mapEngine) {
    this.mapEngine = mapEngine;
    this.layers = new Map(); // 图层缓存
    this.layerGroups = new Map(); // 图层组缓存
    this.layerIndex = 0; // 图层索引计数器

    // 图层类型映射
    this.layerTypes = {
      WMS: 'wms',
      XYZ: 'xyz',
      GEOJSON: 'geojson',
      GRAPHIC: 'graphic',
      GROUP: 'group',
      HEATMAP: 'heatmap',
      CLUSTER: 'cluster'
    };
  }

  /**
   * 获取地图实例
   * @private
   * @returns {mars3d.Map|null} 地图实例
   */
  _getMap() {
    return this.mapEngine?.getInstance() || null;
  }

  /**
   * 生成唯一图层ID
   * @private
   * @param {string} prefix - ID前缀
   * @returns {string} 唯一ID
   */
  _generateLayerId(prefix = 'layer') {
    return `${prefix}_${Date.now()}_${++this.layerIndex}`;
  }

  /**
   * 添加基础底图图层（离线地图）
   * @param {Object} options - 底图配置选项
   * @param {string} options.type - 底图类型 ('global' | 'hebei')
   * @param {string} options.id - 图层ID
   * @param {boolean} options.visible - 是否可见
   * @returns {Object|null} 图层实例
   */
  addBaseLayer(options = {}) {
    const map = this._getMap();
    if (!map) return null;

    const {
      type = 'hebei',
      id = this._generateLayerId('base'),
      visible = true
    } = options;

    const layerConfig = {
      id,
      url: STATIC_SERVER_IP + (type === 'global' ? LAYER_URLS.global : LAYER_URLS.hebei),
      minimumLevel: 0,
      maximumLevel: type === 'global' ? 4 : 13,
      show: visible
    };

    const layer = new mars3d.layer.XyzLayer(layerConfig);
    map.addLayer(layer);

    // 缓存图层
    this.layers.set(id, {
      instance: layer,
      type: this.layerTypes.XYZ,
      config: layerConfig,
      metadata: { baseLayer: true, offline: true }
    });

    return layer;
  }

  /**
   * 添加在线天地图影像底图
   * @param {Object} options - 天地图配置选项
   * @param {string} options.type - 天地图类型 ('img' | 'vec' | 'ter')
   * @param {string} options.id - 图层ID
   * @param {boolean} options.visible - 是否可见
   * @param {string} options.token - 天地图token
   * @returns {Object|null} 天地图图层实例
   */
  addTdtOnlineLayer(options = {}) {
    const map = this._getMap();
    if (!map) return null;

    const {
      type = 'img', // img: 影像, vec: 矢量, ter: 地形
      id = this._generateLayerId('tdt'),
      visible = true,
      token = '6c99c7793f41fccc4bd595b03711913e' // 默认token，建议从配置文件获取
    } = options;

    // 天地图服务配置
    const tdtConfigs = {
      img: {
        layer: 'img_d',
        name: '天地图影像',
        url: `https://t{s}.tianditu.gov.cn/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${token}`,
        subdomains: ['0', '1', '2', '3', '4', '5', '6', '7']
      },
      vec: {
        layer: 'vec_d',
        name: '天地图矢量',
        url: `https://t{s}.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${token}`,
        subdomains: ['0', '1', '2', '3', '4', '5', '6', '7']
      },
      ter: {
        layer: 'ter_d',
        name: '天地图地形',
        url: `https://t{s}.tianditu.gov.cn/ter_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=ter&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${token}`,
        subdomains: ['0', '1', '2', '3', '4', '5', '6', '7']
      }
    };

    const config = tdtConfigs[type];
    if (!config) {
      console.error(`Unsupported TDT type: ${type}`);
      return null;
    }

    const layerConfig = {
      id,
      name: config.name,
      url: config.url,
      subdomains: config.subdomains,
      minimumLevel: 0,
      maximumLevel: 18,
      show: visible
    };

    const layer = new mars3d.layer.XyzLayer(layerConfig);
    map.addLayer(layer);

    // 缓存图层
    this.layers.set(id, {
      instance: layer,
      type: this.layerTypes.XYZ,
      config: layerConfig,
      metadata: { baseLayer: true, online: true, tdtType: type }
    });

    return layer;
  }

  /**
   * 添加天地图注记图层（配合影像使用）
   * @param {Object} options - 注记图层配置
   * @param {string} options.type - 注记类型 ('cia' | 'cva')
   * @param {string} options.id - 图层ID
   * @param {boolean} options.visible - 是否可见
   * @param {string} options.token - 天地图token
   * @returns {Object|null} 注记图层实例
   */
  addTdtAnnotationLayer(options = {}) {
    const map = this._getMap();
    if (!map) return null;

    const {
      type = 'cia', // cia: 影像注记, cva: 矢量注记
      id = this._generateLayerId('tdt_anno'),
      visible = true,
      token = '6c99c7793f41fccc4bd595b03711913e'
    } = options;

    const annoConfigs = {
      cia: {
        name: '天地图影像注记',
        url: `https://t{s}.tianditu.gov.cn/cia_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cia&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${token}`
      },
      cva: {
        name: '天地图矢量注记',
        url: `https://t{s}.tianditu.gov.cn/cva_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${token}`
      }
    };

    const config = annoConfigs[type];
    if (!config) {
      console.error(`Unsupported TDT annotation type: ${type}`);
      return null;
    }

    const layerConfig = {
      id,
      name: config.name,
      url: config.url,
      subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
      minimumLevel: 0,
      maximumLevel: 18,
      show: visible
    };

    const layer = new mars3d.layer.XyzLayer(layerConfig);
    map.addLayer(layer);

    // 缓存图层
    this.layers.set(id, {
      instance: layer,
      type: this.layerTypes.XYZ,
      config: layerConfig,
      metadata: { baseLayer: false, online: true, annotation: true, tdtType: type }
    });

    return layer;
  }

  /**
   * 初始化底图图层（统一入口）
   * @param {Object} options - 底图初始化配置
   * @param {string} options.mapType - 地图类型 ('offline' | 'online')
   * @param {string} options.baseMapType - 底图类型，offline时为'global'|'hebei'，online时为'img'|'vec'|'ter'
   * @param {boolean} options.showAnnotation - 是否显示注记（仅在线地图有效）
   * @param {string} options.tdtToken - 天地图token
   * @returns {Array} 创建的图层数组
   */
  initializeBaseMap(options = {}) {
    const {
      mapType = 'offline', // 'offline' | 'online'
      baseMapType = mapType === 'offline' ? 'hebei' : 'img',
      showAnnotation = true,
      tdtToken = '6c99c7793f41fccc4bd595b03711913e'
    } = options;

    const createdLayers = [];

    try {
      if (mapType === 'offline') {
        // 加载离线地图
        const baseLayer = this.addBaseLayer({
          type: baseMapType,
          visible: true
        });
        if (baseLayer) {
          createdLayers.push(baseLayer);
          console.log(`离线底图加载成功: ${baseMapType}`);
        }
      } else if (mapType === 'online') {
        // 加载在线天地图
        const baseLayer = this.addTdtOnlineLayer({
          type: baseMapType,
          visible: true,
          token: tdtToken
        });
        if (baseLayer) {
          createdLayers.push(baseLayer);
          console.log(`在线天地图底图加载成功: ${baseMapType}`);
        }

        // 添加注记图层
        if (showAnnotation) {
          const annotationType = baseMapType === 'img' ? 'cia' : 'cva';
          const annoLayer = this.addTdtAnnotationLayer({
            type: annotationType,
            visible: true,
            token: tdtToken
          });
          if (annoLayer) {
            createdLayers.push(annoLayer);
            console.log(`天地图注记图层加载成功: ${annotationType}`);
          }
        }
      } else {
        console.error(`不支持的地图类型: ${mapType}`);
      }
    } catch (error) {
      console.error('底图初始化失败:', error);
    }

    return createdLayers;
  }

  /**
   * 切换底图类型
   * @param {Object} options - 切换配置
   * @param {string} options.mapType - 地图类型 ('offline' | 'online')
   * @param {string} options.baseMapType - 底图类型
   * @param {boolean} options.clearExisting - 是否清除现有底图
   * @returns {Array} 新创建的图层数组
   */
  switchBaseMap(options = {}) {
    const { clearExisting = true } = options;

    if (clearExisting) {
      // 清除现有底图
      this.clearBaseLayers();
    }

    // 初始化新底图
    return this.initializeBaseMap(options);
  }

  /**
   * 清除所有底图图层
   */
  clearBaseLayers() {
    const map = this._getMap();
    if (!map) return;

    const baseLayersToRemove = [];
    this.layers.forEach((layerInfo, id) => {
      if (layerInfo.metadata?.baseLayer || layerInfo.metadata?.annotation) {
        baseLayersToRemove.push(id);
      }
    });

    baseLayersToRemove.forEach(id => {
      this.removeLayer(id, true);
    });

    console.log(`清除了 ${baseLayersToRemove.length} 个底图图层`);
  }

  /**
   * 添加WMS图层
   * @param {Object} options - WMS图层配置
   * @param {string} options.url - WMS服务URL
   * @param {string} options.layers - 图层名称
   * @param {Object} options.bbox - 边界框 {minX, minY, maxX, maxY}
   * @param {string} options.id - 图层ID
   * @param {boolean} options.flyTo - 是否飞行到图层范围
   * @param {number} options.opacity - 透明度 (0-1)
   * @returns {Object|null} WMS图层实例
   */
  addWmsLayer(options = {}) {
    const map = this._getMap();
    if (!map) return null;

    const {
      url,
      layers,
      bbox,
      id = layers || this._generateLayerId('wms'),
      flyTo = true,
      opacity = 1,
      parameters = {}
    } = options;

    // 检查是否已存在
    if (this.layers.has(id)) {
      const existingLayer = this.layers.get(id);
      existingLayer.instance.show = true;
      if (flyTo && bbox) {
        this._flyToExtent(bbox);
      }
      return existingLayer.instance;
    }

    // 创建WMS图层
    const layerConfig = {
      id,
      name: `WMS图层_${id}`,
      url,
      layers,
      parameters: { ...WMS_PARAMETERS, ...parameters },
      rectangle: bbox,
      opacity,
      flyTo: false // 手动控制飞行
    };

    const layer = new mars3d.layer.WmsLayer(layerConfig);
    map.addLayer(layer);

    // 飞行到图层范围
    if (flyTo && bbox) {
      this._flyToExtent(bbox);
    }

    // 缓存图层
    this.layers.set(id, {
      instance: layer,
      type: this.layerTypes.WMS,
      config: layerConfig,
      metadata: { bbox }
    });

    return layer;
  }

  /**
   * 添加矢量图层
   * @param {Object} options - 矢量图层配置
   * @param {string} options.type - 矢量类型 ('point' | 'line' | 'polygon')
   * @param {string} options.url - 数据URL或GeoJSON数据
   * @param {Object} options.style - 样式配置
   * @param {string} options.id - 图层ID
   * @param {boolean} options.flyTo - 是否飞行到图层
   * @param {boolean} options.cluster - 是否启用聚合（仅对点图层有效）
   * @returns {Object|null} 矢量图层实例
   */
  addVectorLayer(options = {}) {
    const map = this._getMap();
    if (!map) return null;

    const {
      type = 'point',
      url,
      data,
      style = {},
      id = this._generateLayerId('vector'),
      flyTo = false,
      cluster = false,
      popup = null
    } = options;

    // 根据类型选择不同的处理方式
    let layer;
    const layerConfig = {
      id,
      name: `矢量图层_${type}_${id}`,
      flyTo
    };

    if (data) {
      // 使用GeoJSON数据
      layerConfig.data = data;
    } else if (url) {
      // 使用URL
      layerConfig.url = url;
    } else {
      console.error('Vector layer requires either data or url');
      return null;
    }

    // 设置样式
    layerConfig.symbol = this._buildVectorStyle(type, style);

    // 设置弹窗
    if (popup) {
      layerConfig.popup = popup;
    }

    // 创建图层
    if (cluster && type === 'point') {
      // 聚合点图层
      layer = new mars3d.layer.GraphicLayer(layerConfig);
      // TODO: 实现聚合逻辑
    } else {
      // 普通矢量图层
      layer = new mars3d.layer.GeoJsonLayer(layerConfig);
    }

    map.addLayer(layer);

    // 缓存图层
    this.layers.set(id, {
      instance: layer,
      type: this.layerTypes.GEOJSON,
      config: layerConfig,
      metadata: { vectorType: type, cluster }
    });

    return layer;
  }

  /**
   * 添加热力图图层
   * @param {Object} options - 热力图配置
   * @param {Array} options.data - 热力图数据 [{lng, lat, value}, ...]
   * @param {Object} options.style - 热力图样式
   * @param {string} options.id - 图层ID
   * @returns {Object|null} 热力图图层实例
   */
  addHeatmapLayer(options = {}) {
    const map = this._getMap();
    if (!map) return null;

    const {
      data = [],
      style = {},
      id = this._generateLayerId('heatmap')
    } = options;

    const defaultStyle = {
      radius: 50,
      blur: 15,
      gradient: {
        0.25: "rgb(0,0,255)",
        0.55: "rgb(0,255,0)",
        0.85: "rgb(255,255,0)",
        1.0: "rgb(255,0,0)"
      },
      ...style
    };

    const layerConfig = {
      id,
      name: `热力图_${id}`,
      positions: data,
      ...defaultStyle
    };

    const layer = new mars3d.layer.HeatLayer(layerConfig);
    map.addLayer(layer);

    // 缓存图层
    this.layers.set(id, {
      instance: layer,
      type: this.layerTypes.HEATMAP,
      config: layerConfig,
      metadata: { dataCount: data.length }
    });

    return layer;
  }

  /**
   * 创建图层组
   * @param {Object} options - 图层组配置
   * @param {string} options.id - 图层组ID
   * @param {string} options.name - 图层组名称
   * @param {Array} options.layers - 子图层配置数组
   * @returns {Object|null} 图层组实例
   */
  createLayerGroup(options = {}) {
    const map = this._getMap();
    if (!map) return null;

    const {
      id = this._generateLayerId('group'),
      name = `图层组_${id}`,
      layers = []
    } = options;

    const groupLayer = new mars3d.layer.GroupLayer({ id, name });

    // 添加子图层
    layers.forEach(layerConfig => {
      const childLayer = this._createLayerFromConfig(layerConfig);
      if (childLayer) {
        groupLayer.addLayer(childLayer);
      }
    });

    map.addLayer(groupLayer);

    // 缓存图层组
    this.layerGroups.set(id, {
      instance: groupLayer,
      config: options,
      childLayers: layers
    });

    return groupLayer;
  }

  /**
   * 构建矢量样式
   * @private
   * @param {string} type - 矢量类型
   * @param {Object} style - 样式配置
   * @returns {Object} 完整的样式配置
   */
  _buildVectorStyle(type, style) {
    const defaultStyles = {
      point: {
        type: "billboardP",
        styleOptions: {
          image: ASSETS.icons.tower,
          scale: 0.5,
          scaleByDistance: new Cesium.NearFarScalar(1000, 1, 10000, 0.1),
          clampToGround: true,
          ...style
        }
      },
      line: {
        type: "polylineP",
        styleOptions: {
          color: "#ffff00",
          width: 3,
          clampToGround: true,
          ...style
        }
      },
      polygon: {
        type: "polygonP",
        styleOptions: {
          color: "rgba(255,255,0,0.3)",
          outline: true,
          outlineColor: "#ffff00",
          outlineWidth: 2,
          clampToGround: true,
          ...style
        }
      }
    };

    return defaultStyles[type] || defaultStyles.point;
  }

  /**
   * 根据配置创建图层
   * @private
   * @param {Object} config - 图层配置
   * @returns {Object|null} 图层实例
   */
  _createLayerFromConfig(config) {
    const { type, ...options } = config;

    switch (type) {
      case 'wms':
        return this.addWmsLayer(options);
      case 'vector':
        return this.addVectorLayer(options);
      case 'heatmap':
        return this.addHeatmapLayer(options);
      default:
        console.warn(`Unsupported layer type: ${type}`);
        return null;
    }
  }

  /**
   * 飞行到指定范围
   * @private
   * @param {Object} bbox - 边界框
   */
  _flyToExtent(bbox, options = {}) {
    const map = this._getMap();
    if (!map || !bbox) return;

    const { duration = 0.5 } = options;

    map.flyToExtent({
      xmin: bbox.minX,
      ymin: bbox.minY,
      xmax: bbox.maxX,
      ymax: bbox.maxY
    }, { duration });
  }

  /**
   * 移除图层
   * @param {string} id - 图层ID
   * @param {boolean} destroy - 是否销毁图层
   * @returns {boolean} 是否成功移除
   */
  removeLayer(id, destroy = true) {
    const map = this._getMap();
    if (!map) return false;

    // 检查普通图层
    if (this.layers.has(id)) {
      const layerInfo = this.layers.get(id);
      map.removeLayer(layerInfo.instance, destroy);
      this.layers.delete(id);
      return true;
    }

    // 检查图层组
    if (this.layerGroups.has(id)) {
      const groupInfo = this.layerGroups.get(id);
      map.removeLayer(groupInfo.instance, destroy);
      this.layerGroups.delete(id);
      return true;
    }

    // 尝试直接从地图中移除
    const layer = map.getLayerById(id);
    if (layer) {
      map.removeLayer(layer, destroy);
      return true;
    }

    return false;
  }

  /**
   * 显示/隐藏图层
   * @param {string} id - 图层ID
   * @param {boolean} visible - 是否显示
   * @returns {boolean} 是否成功
   */
  toggleLayerVisibility(id, visible) {
    const layerInfo = this.layers.get(id) || this.layerGroups.get(id);
    if (!layerInfo) {
      // 尝试从地图中直接获取
      const map = this._getMap();
      const layer = map?.getLayerById(id);
      if (layer) {
        layer.show = visible;
        return true;
      }
      return false;
    }

    layerInfo.instance.show = visible;
    return true;
  }

  /**
   * 获取图层信息
   * @param {string} id - 图层ID
   * @returns {Object|null} 图层信息
   */
  getLayerInfo(id) {
    return this.layers.get(id) || this.layerGroups.get(id) || null;
  }

  /**
   * 获取所有图层列表
   * @returns {Array} 图层信息数组
   */
  getAllLayers() {
    const allLayers = [];

    // 普通图层
    this.layers.forEach((layerInfo, id) => {
      allLayers.push({
        id,
        name: layerInfo.config.name || id,
        type: layerInfo.type,
        visible: layerInfo.instance.show,
        metadata: layerInfo.metadata
      });
    });

    // 图层组
    this.layerGroups.forEach((groupInfo, id) => {
      allLayers.push({
        id,
        name: groupInfo.config.name || id,
        type: this.layerTypes.GROUP,
        visible: groupInfo.instance.show,
        childCount: groupInfo.childLayers.length
      });
    });

    return allLayers;
  }

  /**
   * 清除所有图层
   * @param {boolean} keepBaseLayers - 是否保留底图
   */
  clearAllLayers(keepBaseLayers = true) {
    const map = this._getMap();
    if (!map) return;

    // 清除普通图层
    this.layers.forEach((layerInfo, id) => {
      if (!keepBaseLayers || !layerInfo.metadata?.baseLayer) {
        map.removeLayer(layerInfo.instance, true);
        this.layers.delete(id);
      }
    });

    // 清除图层组
    this.layerGroups.forEach((groupInfo, id) => {
      map.removeLayer(groupInfo.instance, true);
      this.layerGroups.delete(id);
    });
  }

  /**
   * 批量添加图层
   * @param {Array} layerConfigs - 图层配置数组
   * @returns {Array} 创建的图层实例数组
   */
  addLayersBatch(layerConfigs = []) {
    const createdLayers = [];

    layerConfigs.forEach(config => {
      try {
        const layer = this._createLayerFromConfig(config);
        if (layer) {
          createdLayers.push(layer);
        }
      } catch (error) {
        console.error('Error creating layer:', error, config);
      }
    });

    return createdLayers;
  }

  /**
   * 获取图层统计信息
   * @returns {Object} 统计信息
   */
  getStatistics() {
    return {
      totalLayers: this.layers.size + this.layerGroups.size,
      layersByType: this._getLayersByType(),
      visibleLayers: this._getVisibleLayersCount(),
      memoryUsage: this._estimateMemoryUsage()
    };
  }

  /**
   * 按类型统计图层
   * @private
   * @returns {Object} 类型统计
   */
  _getLayersByType() {
    const typeCount = {};

    this.layers.forEach(layerInfo => {
      const type = layerInfo.type;
      typeCount[type] = (typeCount[type] || 0) + 1;
    });

    if (this.layerGroups.size > 0) {
      typeCount[this.layerTypes.GROUP] = this.layerGroups.size;
    }

    return typeCount;
  }

  /**
   * 统计可见图层数量
   * @private
   * @returns {number} 可见图层数量
   */
  _getVisibleLayersCount() {
    let count = 0;

    this.layers.forEach(layerInfo => {
      if (layerInfo.instance.show) count++;
    });

    this.layerGroups.forEach(groupInfo => {
      if (groupInfo.instance.show) count++;
    });

    return count;
  }

  /**
   * 估算内存使用量
   * @private
   * @returns {string} 内存使用量估算
   */
  _estimateMemoryUsage() {
    // 简单的内存使用量估算
    const layerCount = this.layers.size + this.layerGroups.size;
    const estimatedMB = layerCount * 2; // 每个图层大约2MB
    return `~${estimatedMB}MB`;
  }

  /**
   * 销毁图层管理器
   */
  destroy() {
    this.clearAllLayers(false);
    this.layers.clear();
    this.layerGroups.clear();
    this.mapEngine = null;
  }
}

/**
 * 图层管理器组合函数
 * @param {Object} mapEngine - 地图引擎实例
 * @returns {Object} 图层管理器API
 */
export function useLayerManager(mapEngine) {
  const manager = ref(null);

  /**
   * 初始化图层管理器
   */
  const initManager = () => {
    manager.value = new LayerManager(mapEngine);
    return manager.value;
  };

  /**
   * 获取管理器实例
   */
  const getManager = () => manager.value;

  /**
   * 销毁管理器
   */
  const destroy = () => {
    if (manager.value) {
      manager.value.destroy();
      manager.value = null;
    }
  };

  return {
    manager,
    initManager,
    getManager,
    destroy
  };
}
